#include <stdio.h>
#include <stdlib.h>
#include "aimage.h"
#include "aimage_utils.h"
#include "aimage_ppm.h"

int compare( const void *e0, const void *e1 )
{
	const APIXEL *p0 = ( const APIXEL * ) e0;
	const APIXEL *p1 = ( const APIXEL * ) e1;

	int i0 = 
			((int) ( p0->r )) * 3 +
			((int) ( p0->g )) * 6 +
			((int) ( p0->b ));

	int i1 = 
			((int) ( p1->r )) * 3 +
			((int) ( p1->g )) * 6 +
			((int) ( p1->b ));

	return i0 - i1;
}

int main( int argc, char *argv[] )
{
	AIMAGE image;
	AIMAGE outimage;
	AIMAGE edgeimage;
	AIMAGE scaled_outimage;
	AIMAGE test_image;
	const int region_size = 32;
	APIXEL region[ region_size * region_size ];

	if ( argc != 1 && argc != 2 )
	{
		fprintf(stderr, "%s [in_file]\n", argv[0] );
		exit( 1 );
	}

	if ( argc == 2 )
	{
		fprintf(stderr,"makemat reading from %s\n", argv[1] );
		AIMAGE_PPM_UTILS::load( image, argv[1] );
	}
	else
	{
		fprintf(stderr,"makemat reading from stdin\n");
		AIMAGE_PPM_UTILS::load( image, "stdin" );
	}

	int xdim, ydim;

	image.get_dim( xdim, ydim );

	fprintf(stderr, "Image is %d by %d\n", xdim, ydim );

	int xmaj_dim, ymaj_dim;

	xmaj_dim = (xdim + region_size - 1 ) / region_size;
	ymaj_dim = (ydim + region_size - 1 ) / region_size;

	outimage.alloc_image( xmaj_dim, ymaj_dim );
	edgeimage.alloc_image( xmaj_dim, ymaj_dim );
	scaled_outimage.alloc_image( xdim, ydim );
	test_image.alloc_image( xdim, ydim );

	for ( int ymaj = 0; ymaj < ymaj_dim; ++ymaj )
	{
		for ( int xmaj = 0; xmaj < xmaj_dim; ++xmaj )
		{
			int x0, y0, x1, y1;
			x0 = xmaj * region_size;
			y0 = ymaj * region_size;
			x1 = x0 + region_size - 1;
			y1 = y0 + region_size - 1;

			if ( x1 >= xdim )
			{
				x1 = xdim-1;
			}
			if ( y1 >= ydim )
			{
				y1 = ydim-1;
			}

			int count = 0;

			for ( int x = x0; x <= x1; ++x )
			{
				for ( int y = y0; y <= y1; ++y )
				{
					image.getpixel( x, y, region[ count ] );
					count++;
				}
			}
			qsort( region, count, sizeof( APIXEL ), compare );
			ACCUM_PIXEL p;
			int samples = count / 5;

			p.r = p.g = p.b = 0;

			for (int i = 0; i < samples; ++i )
			{
				p.r += ( ACCUM_PIXVAL ) region[ i ].r;
				p.g += ( ACCUM_PIXVAL ) region[ i ].g;
				p.b += ( ACCUM_PIXVAL ) region[ i ].b;
			} 
			p.r /= samples;
			p.g /= samples;
			p.b /= samples;

			APIXEL ps;

			ps.r = p.r;
			ps.g = p.g;
			ps.b = p.b;

			outimage.setpixel( xmaj, ymaj, ps ); 
		} 
	}
	AIU::edge( edgeimage, outimage );
	AIU::blank_edges( outimage, edgeimage, .003f );
	AIU::sample( scaled_outimage, outimage, 32 );
	AIU::make_flat_invadjust( test_image, scaled_outimage ); 
	AIMAGE_PPM_UTILS::save( scaled_outimage, "stdout", true );
	//AIMAGE_PPM_UTILS::save( outimage, "stdout", true );
	//AIMAGE_PPM_UTILS::save( edgeimage, "stdout" );
}

